package com.navinfo.opentsp.platform.computing.analysis.application;

import com.mongodb.spark.MongoSpark;
import com.mongodb.spark.config.WriteConfig;
import com.navinfo.opentsp.platform.computing.analysis.entity.BreakdownAdditionDto;
import com.navinfo.opentsp.platform.computing.analysis.entity.VehicleStatusAdditionDto;
import com.navinfo.opentsp.platform.computing.analysis.util.PropertiesUtil;
import com.navinfo.opentsp.platform.computing.analysis.util.TileMap;
import com.navinfo.opentsp.platform.computing.analysis.util.TilePartitioner;
import com.navinfo.opentsp.platform.computing.analysis.util.VehiclePassTimesQuadtree;
import com.navinfo.stream.qingqi.protocol.java.LCStatusType;
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.broadcast.Broadcast;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Tuple2;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

//import com.lc.core.protocol.common.LCLocationData;

/**
 * Created by neo on 2017/6/1.
 */
public class VehiclePassTimesStatisticsBJ {

    private static Logger logger = LoggerFactory.getLogger(VehiclePassTimesStatisticsBJ.class);

    public static void main(String args[]) throws ClassNotFoundException, InterruptedException, ParseException {
        String dateStr = args[0];
        int num = Integer.parseInt(args[1]);
//        int num = 2000;

        SparkSession spark = SparkSession.builder()
                .appName("VehiclePassTimesStatistics")
//                .master("local")
                .config("spark.mongodb.output.uri",
                        PropertiesUtil.getProperties("spark.mongodb.output.uri"))
                .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
                .getOrCreate();

        JavaSparkContext jsc = new JavaSparkContext(spark.sparkContext());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = format.parse(dateStr);
        format.applyPattern("yyyyMMdd");
        String day = format.format(date);
        String hdfsUrl = PropertiesUtil.getProperties("hdfs.path");
        String inputSparkFile = String.format(hdfsUrl, dateStr);
        Dataset<Row> dataset = spark.read().parquet(inputSparkFile);
        Dataset<Row> rrr = dataset.select("vid", "originalLng", "originalLat", "breakdownAddition", "statusAddition");
        Broadcast<HashMap<Long, String>> mapB = TileMap.getInstance(jsc, PropertiesUtil.getProperties("tile.mapping.file.location"));
        System.out.println("1");
        JavaRDD<Row> lines = rrr.toJavaRDD();
//        lines.persist(StorageLevel.MEMORY_AND_DISK_SER_2());

        JavaRDD<String> mapRDD = lines.mapPartitions((FlatMapFunction<Iterator<Row>, String>) iterator -> {
            List<String> list = new ArrayList<>();
            Map tidinserted = new HashMap();
            while (iterator.hasNext()) {
                Row row = iterator.next();
                LocationDataInfo locationDataInfo = LocationDataInfo.parseObj(row);
                HashSet<String> set = new HashSet<String>();
                Long tid = locationDataInfo.getTid();
//                int longitude = locationDataInfo.getLongitude();
//                int latitude = locationDataInfo.getLatitude();

                int lon = locationDataInfo.getOriginallng();
                int lat = locationDataInfo.getOriginallat();

                // 过滤无效数据
                if (lat <= 0 || lon <= 0) {
                    continue;
                }
//                int lon = locationDataInfo.getOriginallng();
//                int lat = locationDataInfo.getOriginallat();
                long tileIdMin = VehiclePassTimesQuadtree.getTileNumber(lat, lon, 15);
                String value = mapB.getValue().get(tileIdMin);
                if (StringUtils.isEmpty(value)) {
                    continue;
                }
                // 判断是否插入过该tid,这么做是为了在reduce操作时合并重复出现在一个区域的点

                if (value != null && StringUtils.isNotEmpty(value)) {

                    if (tidinserted.containsKey(tid + ":" + value)) {
                        // 重复插入该 (车+区域)
                        set.add(value + "," + tid + ":" + tidinserted.get(tid + ":" + value));
                    } else {
                        // 第一次插入该车
                        long m = 0L;
                        long t = 0L;
                        List<VehicleStatusAdditionDto> statusDataList = locationDataInfo.getStatusDataList();
                        if(statusDataList != null){
                            for (VehicleStatusAdditionDto data : statusDataList) {
                                if (data.getTypes().equals(LCStatusType.StatusType.mileage.name())) {
                                    m = data.getStatusValue() * 10;
                                }
                                if (data.getTypes().equals(LCStatusType.StatusType.cumulativeRunningTime.name())) {
                                    t = data.getStatusValue() / 100;
                                }
                            }
                        }

                        List<BreakdownAdditionDto> breakdownList = locationDataInfo.getBreakdownList();
                        int isfault = 0;
                        if(breakdownList != null){
                            for (BreakdownAdditionDto breakdown : breakdownList) {
                                if (breakdown.getBreakdownFMIValue() != 0 && breakdown.getBreakdownSPNValue() != 0) {
                                    isfault = 1;
                                    break;
                                }
                            }
                        }
//                         形式如: 沈阳,辽宁,13112010201:1000:121029120:0
                        set.add(value + "," + tid + ":" + m + ":" + t + ":" + isfault);
                        tidinserted.put(tid + ":" + value, m + ":" + t + ":" + isfault);
                    }
                }
                list.addAll(set);
            }

            return list.iterator();
        });

        System.out.println("2");
        JavaRDD<Document> saveR = mapRDD.mapPartitionsToPair((PairFlatMapFunction<Iterator<String>, String, String>) stringIterator -> {
            HashSet<Tuple2<String, String>> set = new HashSet<Tuple2<String, String>>();
            while (stringIterator.hasNext()) {
                String value = stringIterator.next();
                if (StringUtils.isNotEmpty(value)) {
                    String[] v = value.split(",");
                    //统计市
                    set.add(new Tuple2<String, String>(v[0], v[v.length - 1]));
                    //统计省
                    set.add(new Tuple2<String, String>(v[1], v[v.length - 1]));
                }
            }
//            System.out.println("省市统计信息-------------->" + set.size());
            return set.iterator();
        }).reduceByKey(new Function2<String, String, String>() {
            @Override
            public String call(String v1, String v2) throws Exception {
                return v1 + "," + v2;
            }
        }).map(new Function<Tuple2<String, String>, Document>() {
            @Override
            public Document call(Tuple2<String, String> arg0) throws Exception {

                int type = 0;
                String key = arg0._1;
                String value = arg0._2;

                if (key.endsWith("0000")) {
                    type = 1;
                } else {
                    type = 2;
                }

                HashMap<String, Map> dataHashMap = new HashMap<>();
                String[] dataArray = value.split(",");
                for (String v : dataArray) {
                    // 轮询第一步的rdd
                    // v 形如:13112010201:1000:121029120:0
                    String[] x = v.split(":");
                    if(dataHashMap.containsKey(x)){
                        boolean f = !"0".equals(x[3]);
                        if(f){
                            dataHashMap.get(x).put("f", f);
                        }
                    } else {
                        Map map = new HashMap();
                        map.put("id", Long.valueOf(x[0]));
                        map.put("m", Long.valueOf(x[1]));
                        map.put("t", Long.valueOf(x[2]));
                        map.put("f", !"0".equals(x[3]));
                        dataHashMap.put(x[0], map);
                    }
                }
                Collection<Map> collection =  dataHashMap.values();
                int size = collection.size();

                Document document = new Document();
                try {
                    Map map = new HashMap();
                    map.put("district", Integer.parseInt(key));
                    map.put("times", size);
                    map.put("type", type);
                    map.put("day", Integer.parseInt(day));
                    map.put("dl", collection);
                    document.putAll(map);
                } catch (Exception e) {
                    logger.error("Document parse error", e);
                }
                return document;
            }
        });

        System.out.println("3");
        JavaPairRDD<Long, Long> pair = lines.mapPartitionsToPair((PairFlatMapFunction<Iterator<Row>, Long, Long>) documentIterator -> {
//            System.out.println("mapPartitionsToPair start");
            List<Tuple2<Long, Long>> list = new ArrayList<Tuple2<Long, Long>>();
            while (documentIterator.hasNext()) {
                Row row = documentIterator.next();
                LocationDataInfo locationDataInfo = LocationDataInfo.parseObj(row);
                HashSet<Tuple2<Long, Long>> set = new HashSet<Tuple2<Long, Long>>();
                Long tid = locationDataInfo.getTid();
                int longitude = locationDataInfo.getOriginallng();
                int latitude = locationDataInfo.getOriginallat();
                // 过滤无效数据
                if (latitude <= 0 || longitude <= 0) {
                    continue;
                }
                int lon = locationDataInfo.getOriginallng();
                int lat = locationDataInfo.getOriginallat();
                long tileIdMin = VehiclePassTimesQuadtree.getTileNumber(lat, lon, 15);
                set.add(new Tuple2<Long, Long>(tileIdMin, tid));
                list.addAll(set);
            }
//            System.out.println("mapPartitionsToPair end");
            return list.iterator();
        }).partitionBy(new TilePartitioner(num));
        System.out.println("4");
        JavaRDD<Document> dt = pair.mapPartitions((FlatMapFunction<Iterator<Tuple2<Long, Long>>, Document>) tuple2Iterator -> {

//            System.out.println("mapPartitions start");

            List<Document> dtList = new ArrayList<>();

            HashMap<Long,HashSet<HashMap>> map1 = new HashMap<>(); //15
            HashMap<Long,HashSet<HashMap>> map2 = new HashMap<>(); //14
            HashMap<Long,HashSet<HashMap>> map3 = new HashMap<>(); //13

            while (tuple2Iterator.hasNext()){
                Tuple2<Long, Long> tuple2 = tuple2Iterator.next();

                Long key1 = tuple2._1();
                Long value1 = tuple2._2();

                HashSet<HashMap> set1 = null;
                if (map1.get(key1) == null){
                    set1 = new HashSet<>();
                } else {
                    set1 = map1.get(key1);
                }

                set1.add(createMap(value1, 1));
                map1.put(key1, set1);

                Long key2 = VehiclePassTimesQuadtree.getParentTileId(key1);
                HashSet<HashMap> set2 = null;
                if (map2.get(key2) == null){
                    set2 = new HashSet<>();
                } else {
                    set2 = map2.get(key2);
                }
                set2.add(createMap(value1, 1));
                map2.put(key2,set2);

                Long key3 = VehiclePassTimesQuadtree.getParentTileId(key2);
                HashSet<HashMap> set3 = null;
                if (map3.get(key3) == null){
                    set3 = new HashSet<>();
                } else {
                    set3 = map3.get(key3);
                }
                set3.add(createMap(value1, 1));
                map3.put(key3, set3);
            }
//            System.out.println("mapPartitions middle");
            for(Map.Entry<Long, HashSet<HashMap>> e : map3.entrySet()){
                Long k = e.getKey();
                HashSet<HashMap> v = e.getValue();

                List<Map<String, Object>> list = getChildVidList(k, map2, map1);
                HashMap<String, Object> map = new HashMap<>();
                map.put("dl",list);
                map.put("tile",k);
                map.put("month", getMonth(day));
                map.put("times",v.size());

                int[] zxy = VehiclePassTimesQuadtree.tileIdTozxy(k);

                long lon = VehiclePassTimesQuadtree.tile2lon(zxy[1],zxy[0]);
                long lat = VehiclePassTimesQuadtree.tile2lat(zxy[2],zxy[0]);

                long t15 = VehiclePassTimesQuadtree.getTileNumber(lat, lon, 15);
//                System.out.println("mapB————————————"+mapB.getValue().size());
                String district = mapB.getValue().get(t15);
//                System.out.println("district————————————"+district);

                if (district!=null && !"".equals(district)){
                    map.put("district", Integer.valueOf(district.split(",")[0]));
                }
                dtList.add(new Document(map));
            }
//            System.out.println("mapPartitions end");

            return dtList.iterator();
        });

        System.out.println("5");

        JavaPairRDD<Long, Long> pair1 = lines.mapPartitionsToPair((PairFlatMapFunction<Iterator<Row>, Long, Long>) documentIterator -> {

            List<Tuple2<Long, Long>> list = new ArrayList<Tuple2<Long, Long>>();
            while (documentIterator.hasNext()) {
                Row row = documentIterator.next();
                LocationDataInfo locationDataInfo = LocationDataInfo.parseObj(row);
                Long tid = locationDataInfo.getTid();
                HashSet<Tuple2<Long, Long>> set = new HashSet<Tuple2<Long, Long>>();

                // 过滤无效数据
                if (locationDataInfo.getOriginallat()<=0 || locationDataInfo.getOriginallng()<=0){
                    continue;
                }
                long lat = locationDataInfo.getOriginallat();
                long lon = locationDataInfo.getOriginallng();
                long tileIdMin = VehiclePassTimesQuadtree.getTileNumber(lat, lon, 11);
                set.add(new Tuple2<Long, Long>(tileIdMin, tid));
                list.addAll(set);
            }

            return list.iterator();
        }).partitionBy(new TilePartitioner(num));

        System.out.println("6");
        JavaRDD<Document> dt1 = pair1.mapPartitions((FlatMapFunction<Iterator<Tuple2<Long, Long>>, Document>) tuple2Iterator -> {

            List<Document> dtList = new ArrayList<>();

            HashMap<Long,HashSet<HashMap>> map1 = new HashMap<>(); //11
            HashMap<Long,HashSet<HashMap>> map2 = new HashMap<>(); //10
            HashMap<Long,HashSet<HashMap>> map3 = new HashMap<>(); //9

            while (tuple2Iterator.hasNext()){
                Tuple2<Long, Long> tuple2 = tuple2Iterator.next();

                Long key1 = tuple2._1();
                Long value1 = tuple2._2();

                HashSet<HashMap> set1 = null;
                if (map1.get(key1) == null){
                    set1 = new HashSet<>();
                } else {
                    set1 = map1.get(key1);
                }
                set1.add(createMap(value1, 1));
                map1.put(key1, set1);

                Long key2 = VehiclePassTimesQuadtree.getParentTileId(key1);
                HashSet<HashMap> set2 = null;
                if (map2.get(key2) == null){
                    set2 = new HashSet<>();
                } else {
                    set2 = map2.get(key2);
                }
                set2.add(createMap(value1, 1));
                map2.put(key2,set2);

                Long key3 = VehiclePassTimesQuadtree.getParentTileId(key2);
                HashSet<HashMap> set3 = null;
                if (map3.get(key3) == null){
                    set3 = new HashSet<>();
                } else {
                    set3 = map3.get(key3);
                }
                set3.add(createMap(value1, 1));
                map3.put(key3, set3);
            }

            for(Map.Entry<Long, HashSet<HashMap>> e : map3.entrySet()){
                Long k = e.getKey();
                HashSet<HashMap> v = e.getValue();

                List<Map<String, Object>> list = getChildVidList1(k, map2, map1);
                HashMap<String, Object> map = new HashMap<>();
                map.put("dl",list);
                map.put("tile",k);
                map.put("month", getMonth(day));
                map.put("times",v.size());

                int[] zxy = VehiclePassTimesQuadtree.tileIdTozxy(k);

                long lon = VehiclePassTimesQuadtree.tile2lon(zxy[1],zxy[0]);
                long lat = VehiclePassTimesQuadtree.tile2lat(zxy[2],zxy[0]);

                long t15 = VehiclePassTimesQuadtree.getTileNumber(lat, lon, 15);
                String district = mapB.getValue().get(t15);

                if (district!=null && !"".equals(district)){
                    map.put("district", Integer.valueOf(district.split(",")[1]));
                }
                dtList.add(new Document(map));
            }

            return dtList.iterator();
        });

        Map<String, String> writeOverrides = new HashMap<String, String>();
        writeOverrides.put("collection", "VehicleDrivingNumberInArea_" + day.substring(2, 6));
        WriteConfig writeConfig = WriteConfig.create(jsc).withOptions(writeOverrides);
        MongoSpark.save(saveR, writeConfig);

        Map<String, String> writeOverrides1 = new HashMap<String, String>();
        writeOverrides1.put("collection", "VehicleDrivingNumberInGrid_"+day.substring(2, 6));
        WriteConfig writeConfig1 = WriteConfig.create(jsc).withOptions(writeOverrides1);
        MongoSpark.save(dt, writeConfig1);

        Map<String, String> writeOverrides2 = new HashMap<String, String>();
        writeOverrides2.put("collection", "VehicleDrivingNumberInGrid_"+day.substring(2, 6));
        WriteConfig writeConfig2 = WriteConfig.create(jsc).withOptions(writeOverrides2);
        MongoSpark.save(dt1, writeConfig2);
        jsc.close();
        spark.stop();
    }


    private static List<Map<String, Object>> getChildVidList(Long parent, HashMap<Long,HashSet<HashMap>> map2, HashMap<Long,HashSet<HashMap>> map1) {
        List<Map<String, Object>> list = new ArrayList<>();
        int[] zxy = VehiclePassTimesQuadtree.tileIdTozxy(parent);
        if (zxy[0] == 15) {
            return list;
        }

        long tileIdLt = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1], 2 * zxy[2]);
        long tileIdRt = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1] + 1, 2 * zxy[2]);
        long tileIdLb = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1], 2 * zxy[2] + 1);
        long tileIdRb = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1] + 1, 2 * zxy[2] + 1);

        HashSet<HashMap> ltSet = new HashSet<>();
        HashSet<HashMap> rtSet = new HashSet<>();
        HashSet<HashMap> lbSet = new HashSet<>();
        HashSet<HashMap> rbSet = new HashSet<>();

        if (zxy[0] == 13) {
            if (map2.get(tileIdLt) != null)
                ltSet = map2.get(tileIdLt);
            if (map2.get(tileIdRt) != null)
                rtSet = map2.get(tileIdRt);
            if (map2.get(tileIdLb) != null)
                lbSet = map2.get(tileIdLb);
            if (map2.get(tileIdRb) != null)
                rbSet = map2.get(tileIdRb);
        } else if (zxy[0] == 14) {
            if (map1.get(tileIdLt) != null)
                ltSet = map1.get(tileIdLt);
            if (map1.get(tileIdRt) != null)
                rtSet = map1.get(tileIdRt);
            if (map1.get(tileIdLb) != null)
                lbSet = map1.get(tileIdLb);
            if (map1.get(tileIdRb) != null)
                rbSet = map1.get(tileIdRb);
        }

        HashMap<String, Object> ltMap = new HashMap<>();
        HashMap<String, Object> rtMap = new HashMap<>();
        HashMap<String, Object> lbMap = new HashMap<>();
        HashMap<String, Object> rbMap = new HashMap<>();

        ltMap.put("tile", tileIdLt);
        ltMap.put("times", ltSet.size());

        rtMap.put("tile", tileIdRt);
        rtMap.put("times", rtSet.size());

        lbMap.put("tile", tileIdLb);
        lbMap.put("times", lbSet.size());

        rbMap.put("tile", tileIdRb);
        rbMap.put("times", rbSet.size());

        if(zxy[0]==14){
            ltMap.put("dl", ltSet);
            lbMap.put("dl", lbSet);
            rtMap.put("dl", rtSet);
            rbMap.put("dl", rbSet);
        }else{
            ltMap.put("dl", getChildVidList(tileIdLt, map2, map1));
            lbMap.put("dl", getChildVidList(tileIdLb, map2, map1));
            rtMap.put("dl", getChildVidList(tileIdRt, map2, map1));
            rbMap.put("dl", getChildVidList(tileIdRb, map2, map1));
        }

        list.add(ltMap);
        list.add(rtMap);
        list.add(lbMap);
        list.add(rbMap);

        return list;
    }
    //
//
    private static List<Map<String, Object>> getChildVidList1(Long parent, HashMap<Long,HashSet<HashMap>> map2, HashMap<Long,HashSet<HashMap>> map1) {
        List<Map<String, Object>> list = new ArrayList<>();
        int[] zxy = VehiclePassTimesQuadtree.tileIdTozxy(parent);
        if (zxy[0] == 11) {
            return list;
        }

        long tileIdLt = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1], 2 * zxy[2]);
        long tileIdRt = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1] + 1, 2 * zxy[2]);
        long tileIdLb = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1], 2 * zxy[2] + 1);
        long tileIdRb = VehiclePassTimesQuadtree.xyzToTileId(zxy[0] + 1, 2 * zxy[1] + 1, 2 * zxy[2] + 1);

        HashSet<HashMap> ltSet = new HashSet<>();
        HashSet<HashMap> rtSet = new HashSet<>();
        HashSet<HashMap> lbSet = new HashSet<>();
        HashSet<HashMap> rbSet = new HashSet<>();

        if (zxy[0] == 9) {
            if (map2.get(tileIdLt) != null)
                ltSet = map2.get(tileIdLt);
            if (map2.get(tileIdRt) != null)
                rtSet = map2.get(tileIdRt);
            if (map2.get(tileIdLb) != null)
                lbSet = map2.get(tileIdLb);
            if (map2.get(tileIdRb) != null)
                rbSet = map2.get(tileIdRb);
        } else if (zxy[0] == 10) {
            if (map1.get(tileIdLt) != null)
                ltSet = map1.get(tileIdLt);
            if (map1.get(tileIdRt) != null)
                rtSet = map1.get(tileIdRt);
            if (map1.get(tileIdLb) != null)
                lbSet = map1.get(tileIdLb);
            if (map1.get(tileIdRb) != null)
                rbSet = map1.get(tileIdRb);
        }

        HashMap<String, Object> ltMap = new HashMap<>();
        HashMap<String, Object> rtMap = new HashMap<>();
        HashMap<String, Object> lbMap = new HashMap<>();
        HashMap<String, Object> rbMap = new HashMap<>();

        ltMap.put("tile", tileIdLt);
        ltMap.put("times", ltSet.size());

        rtMap.put("tile", tileIdRt);
        rtMap.put("times", rtSet.size());

        lbMap.put("tile", tileIdLb);
        lbMap.put("times", lbSet.size());

        rbMap.put("tile", tileIdRb);
        rbMap.put("times", rbSet.size());

        if(zxy[0]==10){
            ltMap.put("dl", ltSet);
            lbMap.put("dl", lbSet);
            rtMap.put("dl", rtSet);
            rbMap.put("dl", rbSet);
        }else{
            ltMap.put("dl", getChildVidList(tileIdLt, map2, map1));
            lbMap.put("dl", getChildVidList(tileIdLb, map2, map1));
            rtMap.put("dl", getChildVidList(tileIdRt, map2, map1));
            rbMap.put("dl", getChildVidList(tileIdRb, map2, map1));
        }

        list.add(ltMap);
        list.add(rtMap);
        list.add(lbMap);
        list.add(rbMap);

        return list;
    }

    private static int getMonth(String time) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        long mills = format.parse(time).getTime();
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(mills);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int result = year * 10000 + month * 100;
        if (day <= 10) {
            result += 1;
        } else if (day <= 20) {
            result += 2;
        } else {
            result += 3;
        }
        return result;
    }

    public static HashMap createMap(long tid, int d){
        HashMap m = new HashMap(2){{put("tid", tid);put("d", d);}};
        return m;
    }
    public static class LocationDataInfo {
        private long tid;
        private int longitude;
        private int latitude;
        private int originallng;
        private int originallat;
        private List<VehicleStatusAdditionDto> statusDataList;
        private List<BreakdownAdditionDto> breakdownList;

        public static LocationDataInfo parseObj(Row row){
            if(row == null){
                return null;
            }
            Long tid = Long.parseLong(row.getAs("vid"));
            int lon = row.getAs("originalLng");
            int lat = row.getAs("originalLat");
            Row statusRow = row.getAs("statusAddition");
            List<VehicleStatusAdditionDto> statusAdditionDtos = VehicleStatusAdditionDto.parseRow(statusRow);
            Row breakdownRow = row.getAs("breakdownAddition");
            List<BreakdownAdditionDto> breakdownAdditionDtos = BreakdownAdditionDto.parseRow(breakdownRow);

            LocationDataInfo locationDataInfo = new LocationDataInfo();
            locationDataInfo.setTid(tid);
//            locationDataInfo.setLongitude(longitude);
//            locationDataInfo.setLatitude(latitude);
            locationDataInfo.setOriginallat(lat);
            locationDataInfo.setOriginallng(lon);
            locationDataInfo.setStatusDataList(statusAdditionDtos);
            locationDataInfo.setBreakdownList(breakdownAdditionDtos);
            return locationDataInfo;
        }

        public long getTid() {
            return tid;
        }

        public void setTid(long tid) {
            this.tid = tid;
        }

        public int getLongitude() {
            return longitude;
        }

        public void setLongitude(int longitude) {
            this.longitude = longitude;
        }

        public int getLatitude() {
            return latitude;
        }

        public void setLatitude(int latitude) {
            this.latitude = latitude;
        }

        public int getOriginallng() {
            return originallng;
        }

        public void setOriginallng(int originallng) {
            this.originallng = originallng;
        }

        public int getOriginallat() {
            return originallat;
        }

        public void setOriginallat(int originallat) {
            this.originallat = originallat;
        }


        public List<VehicleStatusAdditionDto> getStatusDataList() {
            return statusDataList;
        }

        public void setStatusDataList(List<VehicleStatusAdditionDto> statusDataList) {
            this.statusDataList = statusDataList;
        }

        public List<BreakdownAdditionDto> getBreakdownList() {
            return breakdownList;
        }

        public void setBreakdownList(List<BreakdownAdditionDto> breakdownList) {
            this.breakdownList = breakdownList;
        }
    }

}
